home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / System7 tools / Frontier / Frontier SDK 2.1 / Toolkits / Applet Toolkit / appletdialogs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-09  |  12.5 KB  |  611 lines  |  [TEXT/KAHL]

  1.  
  2. /*© Copyright 1988-1992 UserLand Software, Inc.  All Rights Reserved.*/
  3.  
  4.  
  5. #include "appletquickdraw.h"
  6. #include "appletops.h"
  7. #include "appletcursor.h"
  8. #include "appletstrings.h"
  9. #include "appletkb.h"
  10. #include "appletresource.h"
  11. #include "appletdialogs.h"
  12.  
  13.  
  14.  
  15.  
  16. void setdialogtext (DialogPtr pdialog, short itemnumber, bigstring bs) {
  17.  
  18.     short itemtype;
  19.     Handle itemhandle;
  20.     Rect itemrect;
  21.     
  22.     GetDItem (pdialog, itemnumber, &itemtype, &itemhandle, &itemrect);
  23.         
  24.     SetIText (itemhandle, bs); 
  25.     } /*setdialogtext*/
  26.     
  27.     
  28. void getdialogtext (DialogPtr pdialog, short itemnumber, bigstring bs) {
  29.  
  30.     short itemtype;
  31.     Handle itemhandle;
  32.     Rect itemrect;
  33.     
  34.     GetDItem (pdialog, itemnumber, &itemtype, &itemhandle, &itemrect);
  35.                 
  36.     GetIText (itemhandle, bs); 
  37.     } /*getdialogtext*/
  38.  
  39.  
  40. void selectdialogtext (DialogPtr pdialog, short itemnumber) {
  41.     
  42.     SelIText (pdialog, itemnumber, 0, infinity); /*select all text*/
  43.     } /*selectdialogtext*/        
  44.  
  45.  
  46. void disabledialogitem (DialogPtr pdialog, short itemnumber) {
  47.     
  48.     short itemtype;
  49.     Handle itemhandle;
  50.     Rect itemrect;
  51.  
  52.     GetDItem (pdialog, itemnumber, &itemtype, &itemhandle, &itemrect);
  53.     
  54.     if (itemtype < itemDisable) { /*it is enabled, disable it*/
  55.     
  56.         SetDItem (pdialog, itemnumber, itemtype + itemDisable, itemhandle, &itemrect);
  57.         
  58.         grayrect (itemrect);
  59.         }
  60.     } /*disabledialogitem*/
  61.     
  62.  
  63. void enabledialogitem (DialogPtr pdialog, short itemnumber) {
  64.     
  65.     short itemtype;
  66.     Handle itemhandle;
  67.     Rect itemrect;
  68.  
  69.     GetDItem (pdialog, itemnumber, &itemtype, &itemhandle, &itemrect);
  70.     
  71.     if (itemtype >= itemDisable) /*it is disabled, enable it*/
  72.     
  73.         SetDItem (pdialog, itemnumber, itemtype - itemDisable, itemhandle, &itemrect);
  74.     } /*disabledialogitem*/
  75.     
  76.  
  77. void dialoggetobjectrect (DialogPtr pdialog, short objectnumber, Rect *r) {
  78.  
  79.     short itemtype;
  80.     Handle itemhandle;
  81.     
  82.     GetDItem (pdialog, objectnumber, &itemtype, &itemhandle, r);
  83.     } /*dialoggetobjectrect*/
  84.     
  85.     
  86. void parsedialogstring (bigstring bs) {
  87.     
  88.     register short i;
  89.     
  90.     for (i = 1; i <= stringlength (bs); i++) {
  91.         
  92.         if (bs [i] == '®')
  93.             bs [i] = (char) 13;
  94.         } /*for*/
  95.     } /*parsedialogstring*/
  96.     
  97.     
  98. static short dialogcountitems (DialogPtr pdialog) {
  99.     
  100.     /*
  101.     amazingly we have to klooge around to find out how many items there are
  102.     in a dialog's item list.
  103.     */
  104.     
  105.     register Handle h;
  106.     
  107.     h = (*(DialogPeek) pdialog).items;
  108.     
  109.     return ((**(short **) h) + 1); /*magic incantation -- Boozer says this works*/
  110.     } /*dialogcountitems*/
  111.  
  112.  
  113. static boolean dialogitemisedittext (DialogPtr pdialog, short item) {
  114.     
  115.     short itemtype;
  116.     Handle itemhandle;
  117.     Rect itemrect;
  118.     
  119.     GetDItem (pdialog, item, &itemtype, &itemhandle, &itemrect);
  120.     
  121.     return (itemtype & editText); 
  122.     } /*dialogitemisedittext*/
  123.     
  124.  
  125. static dialoghasedititems (DialogPtr pdialog) {
  126.     
  127.     register short i;
  128.     register short ctitems;
  129.     
  130.     ctitems = dialogcountitems (pdialog);
  131.     
  132.     for (i = 1; i <= ctitems; i++) 
  133.         if (dialogitemisedittext (pdialog, i))
  134.             return (true);
  135.     
  136.     return (false);
  137.     } /*dialoghasedititems*/
  138.  
  139.  
  140. static dialoggetbuttonstring (DialogPtr pdialog, short item, bigstring bs) {
  141.     
  142.     short itemtype;
  143.     Handle itemhandle;
  144.     Rect itemrect;
  145.  
  146.     GetDItem (pdialog, item, &itemtype, &itemhandle, &itemrect);
  147.     
  148.     copystring ((**(ControlHandle) itemhandle).contrlTitle, bs);
  149.     } /*dialoggetbuttonstring*/
  150.  
  151.  
  152. static void setdefaultitem (DialogPtr pdialog, short defaultitem) {
  153.     
  154.     (*(DialogPeek) pdialog).aDefItem = defaultitem; /*filter will bolden this*/
  155.     } /*setdefaultitem*/
  156.  
  157.  
  158. void boldenbutton (DialogPtr pdialog, short itemnumber) {
  159.  
  160.     /*
  161.     draw a thick black ring around the OK button in the dialog.  
  162.     */
  163.     
  164.     PenState savePen;
  165.     short itemtype;
  166.     Handle itemhandle;
  167.     Rect itemrect;
  168.     
  169.     pushmacport (pdialog);
  170.     
  171.     GetPenState (&savePen); /*save the old pen state*/
  172.     
  173.     GetDItem (pdialog, itemnumber, &itemtype, &itemhandle, &itemrect); /*get the item’s rect*/
  174.     
  175.     InsetRect (&itemrect, -4, -4);
  176.     
  177.     PenSize (3, 3); /*make the pen fatter*/
  178.     
  179.     FrameRoundRect (&itemrect, 16, 16); /*draw the ring*/
  180.  
  181.     SetPenState (&savePen); /*restore the pen state*/
  182.     
  183.     popmacport ();
  184.     } /*boldenbutton*/
  185.  
  186.  
  187. static boolean dialogitemtypeiscontrol (short itemtype) {
  188.     
  189.     register short x;
  190.     
  191.     x = itemtype % itemDisable; /*ignore enabledness*/
  192.     
  193.     return ((x >= ctrlItem) && (x <= (ctrlItem + resCtrl))); 
  194.     } /*dialogitemtypeiscontrol*/
  195.  
  196.  
  197. static boolean dialogitemisbutton (DialogPtr pdialog, short item) {
  198.     
  199.     short itemtype;
  200.     Handle itemhandle;
  201.     Rect itemrect;
  202.     
  203.     if (item <= 0)
  204.         return (false);
  205.     
  206.     GetDItem (pdialog, item, &itemtype, &itemhandle, &itemrect);
  207.     
  208.     return (dialogitemtypeiscontrol (itemtype));
  209.     } /*dialogitemisbutton*/
  210.     
  211.  
  212. static highlightdialogbutton (DialogPtr pdialog, short itemnumber, boolean flon) {
  213.     
  214.     register DialogPtr p = pdialog;
  215.     register short val;
  216.     short itemtype;
  217.     Handle itemhandle;
  218.     Rect itembox;
  219.     
  220.     if (pdialog == nil) /*defensive driving*/
  221.         return;
  222.         
  223.     GetDItem (p, itemnumber, &itemtype, &itemhandle, &itembox);
  224.     
  225.     if (flon)
  226.         val = inButton;
  227.     else
  228.         val = 0;
  229.     
  230.     HiliteControl ((ControlHandle) itemhandle, val); 
  231.     } /*highlightdialogbutton*/
  232.  
  233.  
  234. static boolean dialogitemisenabled (DialogPtr pdialog, short item) {
  235.     
  236.     short itemtype;
  237.     Handle itemhandle;
  238.     Rect itemrect;
  239.     
  240.     GetDItem (pdialog, item, &itemtype, &itemhandle, &itemrect);
  241.     
  242.     return ((itemtype & itemDisable) == 0);
  243.     } /*dialogitemisenabled*/
  244.  
  245.  
  246. static boolean dialogsimulatehit (DialogPtr pdialog, short item) {
  247.     
  248.     if (!(dialogitemisbutton (pdialog, item) && dialogitemisenabled (pdialog, item)))
  249.         return (false);
  250.     
  251.     highlightdialogbutton (pdialog, item, true);
  252.     
  253.     delayticks (8);
  254.     
  255.     highlightdialogbutton (pdialog, item, false);
  256.     
  257.     return (true);
  258.     } /*dialogsimulatehit*/
  259.  
  260.  
  261. static boolean dialogmapkeystroke (DialogPtr pdialog, bigstring bsmap, short *item) {
  262.     
  263.     /*
  264.     map a keystroke onto a dialog item.  if no match, return false.
  265.     
  266.     for buttons, if the keystroke matches the first character of the button name,
  267.     we return true with that item.  makes your choice of button names strategic.
  268.     
  269.     to get the number of items in the list, pull the first two bytes out of the
  270.     dialog's itemhandle and add one.  an obvious problem if Apple changes the format
  271.     of an item list handle.
  272.     
  273.     10/10/91 dmb: now take string to map instead of a character.  if bsmap is 
  274.     longer than a single character, we look for an exact match (still ignoring case).
  275.     
  276.     2/7/92 dmb: use dialoghasedititems instead of looping through item list.
  277.     */
  278.     
  279.     register short i;
  280.     register boolean flcmdkeyrequired;
  281.     short ctitems;
  282.     bigstring bs;
  283.     boolean flsinglechar;
  284.     
  285.     alllower (bsmap); /*search is unicase*/
  286.     
  287.     ctitems = dialogcountitems (pdialog);
  288.     
  289.     flsinglechar = stringlength (bsmap) == 1;
  290.     
  291.     if (flsinglechar) { /*mapping a single character -- check command key*/
  292.         
  293.         flcmdkeyrequired = dialoghasedititems (pdialog);
  294.         
  295.         if (flcmdkeyrequired && !cmdkeydown ())
  296.             return (false);
  297.         }
  298.     
  299.     for (i = 1; i <= ctitems; i++) {
  300.         
  301.         if (dialogitemisbutton (pdialog, i)) {
  302.             
  303.             dialoggetbuttonstring (pdialog, i, bs);
  304.             
  305.             if (stringlength (bs) > 0) {
  306.                 
  307.                 if (flsinglechar)
  308.                     setstringlength (bs, 1);
  309.                 
  310.                 alllower (bs);
  311.                 
  312.                 if (equalstrings (bs, bsmap)) {
  313.                     
  314.                     *item = i;
  315.                     
  316.                     return (true);
  317.                     }
  318.                 }    
  319.             }
  320.         } /*for*/
  321.     
  322.     return (false); /*no mapping for the character*/
  323.     } /*dialogmapkeystroke*/
  324.  
  325.  
  326. DialogPtr newmodaldialog (short id, short defaultitem) {
  327.     
  328.     register DialogPtr pdialog;
  329.     
  330.     cometofront ();
  331.     
  332.     arrowcursor ();
  333.     
  334.     pdialog = GetNewDialog (id, nil, (DialogPtr) -1L);
  335.     
  336.     if (pdialog == nil) 
  337.         return (nil);
  338.         
  339.     centerwindow (pdialog, quickdrawglobal (screenBits).bounds);
  340.     
  341.     ShowWindow (pdialog);    
  342.     
  343.     if (defaultitem > 0)
  344.         boldenbutton (pdialog, defaultitem); 
  345.     
  346.     setdefaultitem (pdialog, defaultitem);
  347.     
  348.     return (pdialog);
  349.     } /*newmodaldialog*/
  350.     
  351.  
  352. static pascal Boolean modaldialogcallback (DialogPtr pdialog, EventRecord *ev, short *item) {
  353.      
  354.      /*
  355.      standard dialog & alert event filtering.
  356.      
  357.      10/3/90 dmb: check result of dialogsimulatehit (which now checks enabledness). 
  358.      only process background tasks on null events; dialog events have priority. 
  359.      also, get default item instead of assuming item 1, and handle boldening.
  360.      
  361.      8/26/91 dmb: after backgrounding, make sure we're still in front.  otherwise, 
  362.      the dialog manager will crash
  363.      
  364.      10/14/91 dmb: set shellevent.when to deter overzealous agent processing
  365.      */
  366.      
  367.      short defaultitem = (*(DialogPeek) pdialog).aDefItem; /*was set by newmodaldialog*/
  368.      short whatevent = (*ev).what;
  369.      bigstring bsbutton;
  370.      
  371.      /*put callback here*/
  372.      
  373.     switch (whatevent) {
  374.     
  375.         case keyDown: case autoKey: {
  376.             
  377.              char chkb;
  378.              boolean flcmdkey;
  379.      
  380.             chkb = (*ev).message & charCodeMask;
  381.             
  382.             flcmdkey = ((*ev).modifiers & cmdKey) == cmdKey;
  383.             
  384.             if ((chkb == chreturn) || (chkb == chenter)) { /*user hit return or enter*/
  385.                 
  386.                 if (defaultitem == 0)
  387.                     return (0);
  388.                 
  389.                 if (!dialogsimulatehit (pdialog, defaultitem))
  390.                     return (0);
  391.                 
  392.                 *item = defaultitem;
  393.                 
  394.                 return (-1); /*the dialog manager's version of true*/
  395.                 }
  396.             
  397.             if ((chkb == chescape) || ((chkb == '.') && flcmdkey)) { /*escape or cmd-period*/
  398.                 
  399.                 getresourcestring (cancelbuttonstring, bsbutton);
  400.                 }
  401.             else
  402.                 setstringwithchar (chkb, bsbutton);
  403.             
  404.             if (dialogmapkeystroke (pdialog, bsbutton, item)) {
  405.                 
  406.                 if (MenuKey ((*ev).message & charCodeMask)) { /*will be handled by system*/
  407.                     
  408.                     HiliteMenu (0);
  409.                     
  410.                     break;
  411.                     }
  412.                 
  413.                 if (!dialogsimulatehit (pdialog, *item))
  414.                     return (0);
  415.                 
  416.                 return (-1);
  417.                 }
  418.             
  419.             break; /*keydown or autokey*/
  420.             }
  421.         
  422.         case updateEvt:
  423.         
  424.             if ((defaultitem > 0) && ((*ev).message == (long) pdialog))
  425.                 boldenbutton (pdialog, defaultitem);
  426.             
  427.             break;
  428.         
  429.         case nullEvent:
  430.             SelectWindow (pdialog); /*make sure no one has screwed around with us*/
  431.             
  432.             break;
  433.         
  434.         } /*switch*/
  435.     
  436.     return (0); /*the dialog manager's version of false*/
  437.     } /*modaldialogcallback*/
  438.  
  439.  
  440. short runmodaldialog (void) {
  441.     
  442.     short itemnumber;
  443.     
  444.     ModalDialog (&modaldialogcallback, &itemnumber);
  445.     
  446.     return (itemnumber);
  447.     } /*runmodaldialog*/
  448.     
  449.     
  450. boolean alertdialog (bigstring bs) {
  451.     
  452.     #define alertdialogid 128 
  453.     #define alertokitem 1
  454.     #define alertmsgitem 3
  455.     register DialogPtr pdialog;
  456.     
  457.     sysbeep;
  458.     
  459.     parsedialogstring (bs);
  460.     
  461.     if ((pdialog = newmodaldialog (alertdialogid, alertokitem)) == nil)
  462.         return (false);
  463.     
  464.     setdialogtext (pdialog, alertmsgitem, bs);
  465.     
  466.     ShowWindow (pdialog);
  467.     
  468.     runmodaldialog ();
  469.     
  470.     DisposDialog (pdialog);
  471.     
  472.     return (true);
  473.     } /*alertdialog*/
  474.     
  475.     
  476. short savedialog (bigstring fname) {
  477.     
  478.     /*
  479.     as the user to save changes before closing the file.
  480.     
  481.     we return 1 if they chose Yes, 2 for No, 3 for Cancel.
  482.     */
  483.     
  484.     #define savedialogid 131 
  485.     #define saveyesitem 1
  486.     #define savenoitem 2
  487.     #define savecancelitem 3
  488.     #define savemsgitem 4
  489.     register DialogPtr pdialog;
  490.     register short item;
  491.     bigstring bs;
  492.     short choice;
  493.     
  494.     copystring ("\pSave “", bs);
  495.     
  496.     pushstring (fname, bs);
  497.     
  498.     pushstring ("\p” before closing?", bs);
  499.     
  500.     if ((pdialog = newmodaldialog (savedialogid, saveyesitem)) == nil)
  501.         return;
  502.     
  503.     setdialogtext (pdialog, savemsgitem, bs);
  504.     
  505.     ShowWindow (pdialog);
  506.     
  507.     switch (runmodaldialog ()) {
  508.         
  509.         case saveyesitem:
  510.             choice = 1;
  511.             
  512.             break;
  513.             
  514.         case savenoitem:
  515.             choice = 2;
  516.             
  517.             break;
  518.             
  519.         case savecancelitem:
  520.             choice = 3;
  521.             
  522.             break;
  523.             
  524.         } /*switch*/
  525.     
  526.     DisposDialog (pdialog);
  527.     
  528.     return (choice);
  529.     } /*savedialog*/
  530.  
  531.  
  532. boolean confirmdialog (bs) bigstring bs; {
  533.     
  534.     #define confirmdialogid 129 
  535.     #define confirmokitem 1
  536.     #define confirmcancelitem 2
  537.     #define confirmmsgitem 3
  538.     register DialogPtr pdialog;
  539.     register short item;
  540.     
  541.     parsedialogstring (bs);
  542.     
  543.     if ((pdialog = newmodaldialog (confirmdialogid, confirmokitem)) == nil)
  544.         return (false);
  545.     
  546.     setdialogtext (pdialog, confirmmsgitem, bs);
  547.     
  548.     ShowWindow (pdialog);
  549.     
  550.     item = runmodaldialog ();
  551.     
  552.     DisposDialog (pdialog);
  553.     
  554.     return (item == confirmokitem);
  555.     } /*confirmdialog*/
  556.  
  557.  
  558. boolean askdialog (bigstring bsprompt, bigstring bsanswer) {
  559.     
  560.     /*
  561.     put up the standard "ask" dialog, with the provided prompt and return
  562.     true if the user clicked on ok.  the answer is in bsanswer.
  563.     */
  564.     
  565.     #define askdialogid 130
  566.     #define askokitem 1
  567.     #define askcancelitem 2
  568.     #define askpromptitem 3
  569.     #define askansweritem 4    
  570.     register DialogPtr pdialog;
  571.     register short itemnumber;
  572.     
  573.     ParamText (bsprompt, emptystring, emptystring, emptystring);
  574.     
  575.     if ((pdialog = newmodaldialog (askdialogid, askokitem)) == nil)
  576.         return (false);
  577.     
  578.     setdialogtext (pdialog, askansweritem, bsanswer);
  579.     
  580.     selectdialogtext (pdialog, askansweritem);
  581.     
  582.     ShowWindow (pdialog);
  583.     
  584.     itemnumber = runmodaldialog ();
  585.     
  586.     getdialogtext (pdialog, askansweritem, bsanswer);
  587.     
  588.     DisposDialog (pdialog);
  589.     
  590.     return (itemnumber == askokitem);
  591.     } /*askdialog*/
  592.  
  593.  
  594. boolean oserror (OSErr errcode) {
  595.     
  596.     bigstring bs;
  597.     
  598.     if (errcode == noErr)
  599.         return (false);
  600.     
  601.     copystring ("\pMacintosh OS Error = ", bs);
  602.     
  603.     pushint (errcode, bs);
  604.     
  605.     alertdialog (bs);
  606.     
  607.     return (true);
  608.     } /*oserror*/
  609.     
  610.     
  611.